package com.young4j.xinsuiwutuobang.util;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import com.young4j.xinsuiwutuobang.annotation.Action;
import com.young4j.xinsuiwutuobang.bean.Handler;
import com.young4j.xinsuiwutuobang.bean.Request;

/**
 * 通过该类，获取所有定义了Controller注解的类，可以通过反射获取该类中
 * 素有带了Action注解的方法，获取Action注解中的请求表达式，进而获取
 * 请求方法与请求路径，封装一个请求对象Request与处理对象Handler，最后通过
 * Request与Handler建立一个映射关系，放入一个Action Map中，并提供一个可
 * 根据请求方法与请求路径获取处理对象的方法
 * @author 杨飞
 *
 */
public final class ControllerHellper {
	/**
	 * 用于处理请求与处理器之间的映射关系--Action Map
	 * 
	 * 通过它来存放Request与Handler之间的映射关系，然后通过ClassHelper来获取所有带有Controller注解的类，
	 * 接着遍历这些Controller类，从Action中注解中提取URL，最后初始化Request与Handler之间的映射关系
	 * 
	 * 获取所有Controller类
	 * 遍历所有类
	 * 拿到类中的素有方法
	 * 遍历所有方法
	 * 找到有Action注解的方法
	 * 从Action中获取URL映射规则
	 * 验证映射规则
	 * 获取请求方法和请求路径
	 * 初始化Request，Handler
	 */
	private static final Map<Request,Handler> ACTION_MAP = new HashMap<Request,Handler>();
	static{
		Set<Class<?>> controllerClassSet = ClassHelper.getControllerClassSet();
		if(CollectionUtils.isNotEmpty(controllerClassSet)){
			for(Class<?> controllerClass : controllerClassSet){
				Method[] methods = controllerClass.getDeclaredMethods();
				if(ArrayUtils.isNotEmpty(methods)){
					for(Method method : methods){
						if(method.isAnnotationPresent(Action.class)){
							Action action = method.getAnnotation(Action.class);
							String mapping = action.value();
							if(mapping.matches("\\w+:/\\w*")){
								String[] array = mapping.split(":");
								if(ArrayUtils.isNotEmpty(array) && array.length == 2){
									String requestMethod = array[0];
									String requestPath = array[1];
									Request request = new Request(requestMethod, requestPath);
									Handler handler = new Handler(controllerClass, method);
									ACTION_MAP.put(request, handler);
								}
							}
						}
					}
				}
			}
		}
	}
	/**
	 * 获取Handler
	 * 
	 * 根据Request获取Handler
	 * @param requestMethod
	 * @param requestPath
	 * @return
	 */
	public static Handler getHandler(String requestMethod,String requestPath){
		Request request = new Request(requestMethod,requestPath);
		return ACTION_MAP.get(request);
	}
}
